【アップデート】LambdaがCloudWatch Application SignalsによるAPMをサポートするようになりました!

【アップデート】LambdaがCloudWatch Application SignalsによるAPMをサポートするようになりました!

Clock Icon2024.11.22

リテールアプリ共創部@大阪の岩田です。

2024/11/21付けのアップデートでLambdaがCloudWatch Application SignalsによるApplication Performance Monitoring(APM)をサポートするようになりました。

https://aws.amazon.com/about-aws/whats-new/2024/11/aws-lambda-application-performance-monitoring-cloudwatch-signals/

さっそく触ってみたので簡単に紹介させて頂きます。

アップデートの概要

これまでApplication Signalsでサポートされていたコンピューティング環境はEC2,ECS,EKSの3つでしたが、今回のアップデートによってLambdaも追加されました!
現時点では以下のランタイムがサポートされています。

  • Python 3.10
  • Python 3.11
  • Python 3.12
  • Python 3.13
  • Node.js 18.x
  • Node.js 20.x
  • Node.js 22.x

注意点としてNode.jsについてはESモジュールはサポートされておらず、CommonJSのみサポートされています。
これはOpenTelemetry JavaScriptがESモジュールを正式サポートしていないためのようです。

仕組みとしてはAWSが用意するレイヤーをLambdaに紐づけ、各種環境変数を設定することでLambdaとApplication Signalsがよしなに連携してくれるというものです。

やってみる

それでは実際にLambdaとApplication Signalsを連携させていきます。今回はPython3.13のランタイムを利用しています。

最低限やることは以下の4つです。

  • Lambda実行ロールに必要な権限を付与
    • CloudWatchLambdaApplicationSignalsExecutionRolePolicyというマネージドポリシーが用意されているので、これを利用するのが楽です
  • Lambdaの環境変数AWS_LAMBDA_EXEC_WRAPPER/opt/otel-instrumentを設定
  • AWSが提供するレイヤーAWSOpenTelemetryDistroPython/AWSOpenTelemetryDistroJsを紐づけ
  • Lambdaの設定でApplication Signalsを有効化
    • X-Rayのアクティブトレースも合わせて有効化するのが推奨されています

設定例としてはこんな感じになります。

Lambdaの環境変数

Lambdaのモニタリング関連設定

この状態で以下のコードを実行してみます。

import json
import boto3
import requests

s3_client = boto3.client('s3')
dynamodb_client = boto3.client('dynamodb')

def lambda_handler(event, context):
    s3_client.list_buckets()
    dynamodb_client.list_tables()
    requests.get('https://dev.classmethod.jp')
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

requestsを利用していますが、AWSOpenTelemetryDistroPythonのレイヤーにrequestsも内包されているため、特に追加のレイヤーを導入無しで利用可能になっています。

しばらく待つとApplication Signalsから対象のLambdaが確認できるようになります。

Application SignalsにLambdaの情報が表示される

この辺りの情報はCW Logsのロググループ/aws/application-signals/dataに出力された結果をサマリして表示しているようです。ログの本体はこんな感じです。

Application Signals関係のログ

X-Rayのトレース結果を確認すると以下の通りS3とDynamoDBへのアクセスもしっかりトレースできています。

X-Rayのトレース結果

従来はX-Ray SDKを利用してpatchを適用するなどの手順が必要でしたが、AWSOpenTelemetryDistroPythonのレイヤーがよしなに自動インストルメンテーションしてくれているので、Lambdaのコード上では特に手動のインストルメンテーション無しでトレースできています。

一方でrequestsを使用してhttps://dev.classmethod.jpにアクセスしている部分はうまくトレースできていません。これはAWS_LAMBDA_EXEC_WRAPPERに指定した初期処理の中で環境変数OTEL_PYTHON_DISABLED_INSTRUMENTATIONSが自動的に設定されており、requestsの自動インストルメンテーションが無効化されているためです。該当箇所の処理は以下の通りです。

if [ -z ${OTEL_PYTHON_DISABLED_INSTRUMENTATIONS} ]; then
    export OTEL_PYTHON_DISABLED_INSTRUMENTATIONS="aio-pika,aiohttp-client,aiohttp-server,aiopg,asgi,asyncio,asyncpg,boto,boto3,cassandra,celery,confluent_kafka,dbapi,django,elasticsearch,falcon,fastapi,flask,grpc_client,grpc_server,grpc_aio_client,grpc_aio_server,httpx,jinja2,kafka,logging,mysql,mysqlclient,pika,psycopg,psycopg2,pymemcache,pymongo,pymysql,pyramid,redis,remoulade,requests,sklearn,sqlalchemy,sqlite3,starlette,system_metrics,threading,tornado,tortoiseorm,urllib,urllib3,wsgi"
fi
export OTEL_PYTHON_DISABLED_INSTRUMENTATIONS="$OTEL_PYTHON_DISABLED_INSTRUMENTATIONS,aws-lambda";

この辺りの細かな仕様把握はレイヤーをダウンロードしてソースコードを読むのが手っ取り早いと思います。

レイヤーのソースコードはAWS CLIからget-layer-version-by-arnを実行し、レスポンスに含まれるPresigned-URLからダウンロード可能です。例として以下のようなコマンドを実行すればPresigned-URLが取得できます。

aws lambda get-layer-version-by-arn --region us-east-1 --arn arn:aws:lambda:us-east-1:615299751070:layer:AWSOpenTelemetryDistroPython:5 | jq .Content.Location

ということでLambdaの環境変数OTEL_PYTHON_DISABLED_INSTRUMENTATIONSを設定してrequestsも自動インストルメンテーションされるようにしてみましょう。設定する値はrequestsが入っていなければなんでも良いのですが、aws-lambdaは自動的にOTEL_PYTHON_DISABLED_INSTRUMENTATIONSに追加されるようなので、ここではaws-lambdaを指定してみました。

Lambdaの環境変数(更新後)

改めてLambdaを実行してトレース結果を確認すると、今度はhttps://dev.classmethod.jpへのリクエストもトレースできていることが分かります。

X-Rayのトレース結果その2

自動インストルメンテーションの対象は環境変数OTEL_PYTHON_DISABLED_INSTRUMENTATIONSで調整していくと良さそうですね。

Application Signalsの「依存関係」からもdev.classmethod.jpに関するメトリクスが見えるようになっています。

Application Signalsの「依存関係」

まとめ

簡単にですがLambda × Application Signalsを試してみました。

Lambdaのコード修正無しに自動インストルメンテーションできるのはお手軽かつ非常に便利ですね。クラウドサービスを活用したシステムにとってAPMは非常に重要なので、こういった便利な機能をうまく活用していきたいですね。

参考

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.